/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.idl;

import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Vector;

class TypeDef extends TypeDeclaration {
	public TypeDeclarator type_declarator;
	private Vector typeSpecs = new Vector();

	public TypeDef(int num) {
		super(num);
		pack_name = "";
	}

	public void setPackage(String s) {
		s = parser.pack_replace(s);
		if (pack_name.length() > 0)
			pack_name = new String(s + "." + pack_name);
		else
			pack_name = s;
		type_declarator.setPackage(s);
	}

	public void set_included(boolean i) {
		included = i;
	}

	public void setEnclosingSymbol(IdlSymbol s) {
		if (enclosing_symbol != null && enclosing_symbol != s) {
			System.err.println("was " + enclosing_symbol.getClass().getName()
					+ " now: " + s.getClass().getName());
			throw new RuntimeException(
					"Compiler Error: trying to reassign container for " + name);
		}
		enclosing_symbol = s;
		type_declarator.setEnclosingSymbol(s);
	}

	public void parse() {
		for (Enumeration e = type_declarator.declarators.v.elements(); e
				.hasMoreElements();) {
			Declarator d = (Declarator) e.nextElement();
			d.escapeName();

			try {
				AliasTypeSpec alias = new AliasTypeSpec(
						(TypeSpec) type_declarator.type_spec());

				/* arrays need special treatment */

				if (d.d instanceof ArrayDeclarator) {
					// we don't parse the declarator itself
					// as that would result in its name getting defined
					// we define the declarator's name as a type name indirectly
					// through the cloned type specs.

					alias = new AliasTypeSpec(new ArrayTypeSpec(new_num(),
							alias.originalType(), (ArrayDeclarator) d.d,
							pack_name));
					alias.parse();
				} else {
					if (!(e.hasMoreElements()))
						alias.parse();
				}
				alias.set_name(d.name());
				alias.setPackage(pack_name);
				alias.setEnclosingSymbol(enclosing_symbol);
				alias.set_token(d.d.get_token());
				alias.set_included(included);

				typeSpecs.addElement(alias);
				NameTable.define(d.full_name(), "type");
				TypeMap.typedef(d.full_name(), alias);
			} catch (NameAlreadyDefined n) {
				parser.error("TypeDef'd name " + d.name()
						+ " already defined. ", d.token);
			}
		}
	}

	public void print(PrintWriter ps) {
		if (included && !generateIncluded())
			return;

		for (Enumeration e = typeSpecs.elements(); e.hasMoreElements();) {
			((AliasTypeSpec) e.nextElement()).print(ps);
		}

	}

}
